import json
import redis
from typing import Dict, List, Any, Optional, Union


class RedisClient:
    """Redis客户端，用于处理JSON格式的异常数据。"""
    
    def __init__(self, host='localhost', port=6379, db=0, password=None, decode_responses=True):
        """
        初始化Redis客户端。
        
        参数:
            host (str): Redis主机地址
            port (int): Redis端口
            db (int): Redis数据库编号
            password (str, optional): Redis密码
            decode_responses (bool): 自动将响应的字节解码为字符串
        """
        self.redis_client = redis.Redis(
            host=host,
            port=port,
            db=db,
            password=password,
            decode_responses=decode_responses
        )
    
    def get_json_data(self, key: str) -> Optional[Dict[str, Any]]:
        """
        通过键获取Redis中的JSON数据。
        
        参数:
            key (str): Redis键
            
        返回:
            Dict或None: 解析后的JSON数据，如果键不存在则返回None
        """
        data = self.redis_client.get(key)
        if data:
            try:
                return json.loads(data)
            except json.JSONDecodeError:
                print(f"解析键为{key}的JSON数据时出错")
                return None
        return None
    
    def get_anomalies(self, key: str) -> List[Dict[str, Any]]:
        """
        通过键获取Redis中的异常数据列表。
        
        参数:
            key (str): Redis键
            
        返回:
            List: 异常数据字典列表，如果键不存在或没有异常数据则返回空列表
        """
        data = self.get_json_data(key)
        if data and isinstance(data, dict) and 'anomalies' in data:
            return data['anomalies']
        return []
    
    def get_analysis_request(self, key: str) -> Optional[Dict[str, Any]]:
        """
        通过键获取Redis中的分析请求数据。
        
        参数:
            key (str): Redis键
            
        返回:
            Dict或None: 分析请求数据字典，如果未找到则返回None
        """
        data = self.get_json_data(key)
        if data and isinstance(data, dict) and 'analysis_request' in data:
            return data['analysis_request']
        return None
    
    def get_anomalies_by_type(self, key: str, anomaly_type: str) -> List[Dict[str, Any]]:
        """
        从Redis获取按类型过滤的异常数据。
        
        参数:
            key (str): Redis键
            anomaly_type (str): 要过滤的异常类型（例如，'cpu'，'memory'）
            
        返回:
            List: 过滤后的异常数据列表
        """
        anomalies = self.get_anomalies(key)
        return [a for a in anomalies if a.get('type') == anomaly_type]
    
    def get_anomalies_by_severity(self, key: str, severity: str) -> List[Dict[str, Any]]:
        """
        从Redis获取按严重程度过滤的异常数据。
        
        参数:
            key (str): Redis键
            severity (str): 要过滤的严重程度级别（例如，'critical'，'alert'，'warning'，'info'）
            
        返回:
            List: 过滤后的异常数据列表
        """
        anomalies = self.get_anomalies(key)
        return [a for a in anomalies if a.get('severity') == severity]
    
    def get_anomalies_by_device(self, key: str, device: str) -> List[Dict[str, Any]]:
        """
        从Redis获取按设备过滤的异常数据。
        
        参数:
            key (str): Redis键
            device (str): 要过滤的设备名称（例如，'server-01'）
            
        返回:
            List: 过滤后的异常数据列表
        """
        anomalies = self.get_anomalies(key)
        return [a for a in anomalies if a.get('device') == device]
    
    def get_anomalies_with_impact(self, key: str, impact: str) -> List[Dict[str, Any]]:
        """
        从Redis获取按业务影响程度过滤的异常数据。
        
        参数:
            key (str): Redis键
            impact (str): 要过滤的业务影响程度（例如，'high'，'moderate'，'low'）
            
        返回:
            List: 过滤后的异常数据列表
        """
        anomalies = self.get_anomalies(key)
        return [a for a in anomalies if a.get('business_impact') == impact]
    
    def get_anomalies_for_service(self, key: str, service: str) -> List[Dict[str, Any]]:
        """
        从Redis获取影响特定服务的异常数据。
        
        参数:
            key (str): Redis键
            service (str): 要过滤的服务名称（例如，'web'，'api'）
            
        返回:
            List: 过滤后的异常数据列表
        """
        anomalies = self.get_anomalies(key)
        return [a for a in anomalies if service in a.get('affected_services', [])] 